#include <stdio.h>
#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio.h"
#include "iot_pwm.h"
#include "iot_errno.h"
#include "hi_io.h"

#define RED_LED_PIN_NAME 2
#define BULE_LED_PIN_NAME 7
#define GREEN_LED_PIN_NAME 8

// GPIO9控制LED
#define LED_TASK_GPIO 9
// GPIO5控制按键
#define BUTTON_TASK_GPIO 14

#define LED_INTERVAL_TIME 30
#define LED_TASK_STACK_SIZE 512
#define LED_TASK_PRIO 25

#define IOT_PWM_DUTY_MAX 100
#define PWM_FREQ_DIVITION 64000
#define DELAY_US 250000
#define STACK_SIZE (4096)
#define PWM0_PORT_NUM (0)
#define PWM1_PORT_NUM (1)
#define PWM2_PORT_NUM (2)
#define DOUBLE (2)

enum LedState
{
    LED_RED = 0,
    LED_GREEN,
    LED_BULE,
};

enum LedState g_ledState = LED_RED;

static void LedTask()
{
    while (1)
    {
        switch (g_ledState)
        {
        case LED_RED:
            // 控制灯开
            IoTGpioInit(RED_LED_PIN_NAME);
            hi_io_set_func(RED_LED_PIN_NAME, HI_IO_FUNC_GPIO_2_PWM2_OUT);
            IoTPwmInit(PWM2_PORT_NUM);
            for (int i = 1; i < IOT_PWM_DUTY_MAX; i *= DOUBLE)
            {
                IoTPwmStart(PWM2_PORT_NUM, i, PWM_FREQ_DIVITION);
                usleep(DELAY_US);
                IoTPwmStop(PWM2_PORT_NUM);
            }
            break;
        case LED_GREEN:
            // 控制灯关
            IoTGpioInit(GREEN_LED_PIN_NAME);
            hi_io_set_func(GREEN_LED_PIN_NAME, HI_IO_FUNC_GPIO_8_PWM1_OUT);
            IoTPwmInit(PWM1_PORT_NUM);
            for (int i = 1; i < IOT_PWM_DUTY_MAX; i *= DOUBLE)
            {
                IoTPwmStart(PWM1_PORT_NUM, i, PWM_FREQ_DIVITION);
                usleep(DELAY_US);
                IoTPwmStop(PWM1_PORT_NUM);
            }
            break;
        case LED_BULE:
            // 控制灯闪
            IoTGpioInit(BULE_LED_PIN_NAME);
            hi_io_set_func(BULE_LED_PIN_NAME, HI_IO_FUNC_GPIO_7_PWM0_OUT);
            IoTPwmInit(PWM0_PORT_NUM);
            for (int i = 1; i < IOT_PWM_DUTY_MAX; i *= DOUBLE)
            {
                IoTPwmStart(PWM0_PORT_NUM, i, PWM_FREQ_DIVITION);
                usleep(DELAY_US);
                IoTPwmStop(PWM0_PORT_NUM);
            }
            break;
        }
    }
}

static void OnButtonPressed()
{
    static int cnt = 0;
    enum LedState nextState = LED_RED;
    switch (g_ledState)
    {
    case LED_RED:
        nextState = LED_GREEN;
        break;
    case LED_GREEN:
        nextState = LED_BULE;
        break;
    case LED_BULE:
        nextState = LED_RED;
        break;
    default:
        break;
    }
    g_ledState = nextState;
}

static void LedExampleEntry(void)
{
    // LED的GPIO9初始化
    IoTGpioInit(LED_TASK_GPIO);
    hi_io_set_func(LED_TASK_GPIO, HI_IO_FUNC_GPIO_9_GPIO);
    // 设置为输出
    IoTGpioSetDir(LED_TASK_GPIO, IOT_GPIO_DIR_OUT);

    // 按键GPIO5初始化
    IoTGpioInit(BUTTON_TASK_GPIO);
    // 模式设置为标准GPIO
    hi_io_set_func(BUTTON_TASK_GPIO, HI_IO_FUNC_GPIO_14_GPIO);
    // 设置为输入
    IoTGpioSetDir(BUTTON_TASK_GPIO, IOT_GPIO_DIR_IN);
    // 拉高GPIO5电平等待后续按键事件触发
    hi_io_set_pull(BUTTON_TASK_GPIO, HI_IO_PULL_UP);
    // 注册按键中断处理函数
    IoTGpioRegisterIsrFunc(BUTTON_TASK_GPIO, IOT_INT_TYPE_EDGE, IOT_GPIO_EDGE_RISE_LEVEL_HIGH, OnButtonPressed, NULL);

    osThreadAttr_t attr;

    attr.name = "LedTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = LED_TASK_STACK_SIZE;
    attr.priority = LED_TASK_PRIO;

    if (osThreadNew((osThreadFunc_t)LedTask, NULL, &attr) == NULL)
    {
        printf("[LedExample] Falied to create LedTask!\n");
    }
}

SYS_RUN(LedExampleEntry);
